package leetcode.code0592;

import leetcode.IDebug;
import leetcode.helper.HelpDebug;

//执行用时：1 ms, 在所有 Java 提交中击败了98.91%的用户
//
//内存消耗：39.3 MB, 在所有 Java 提交中击败了9.24%的用户
//
//通过测试用例：105 / 105
public class Solution implements IDebug {

	@Override
	public void debug1() {
		HelpDebug.compare("0/1", this.fractionAddition("-1/2+1/2"));

	}

	@Override
	public void debug2() {
		HelpDebug.compare("1/3", this.fractionAddition("-1/2+1/2+1/3"));

	}

	@Override
	public void debug3() {
		HelpDebug.compare("-1/6", this.fractionAddition("1/3-1/2"));
	}

	@Override
	public void debug4() {

	}

	public String fractionAddition(String expression) {
		MaxNumber ans = new MaxNumber();
		char[] cs = expression.toCharArray();
		int len = cs.length;
		int up = 0, down = 1;
		char op = '+';
		int p = 0;
		boolean isUp = true;
		while (p < len) {
			char c = cs[p];
			if (c == '+' || c == '-') {
				if (op == '+') {
					ans = ans.add(up, down);
				} else {
					ans = ans.sub(up, down);
				}
				op = c;
				up = 0;
				isUp = true;
			} else if (c == '/') {
				isUp = false;
				down = 0;
			} else if (isUp) {
				up = up * 10 + c - '0';
			} else {
				down = down * 10 + c - '0';
			}
			p++;
		}
		if (op == '+') {
			ans = ans.add(up, down);
		} else {
			ans = ans.sub(up, down);
		}
		return ans.toString();
	}

	public class MaxNumber {
		int up;
		int down;

		public MaxNumber() {
			this.up = 0;
			this.down = 1;
		}

		public MaxNumber(int up, int down) {
			this.up = up;
			this.down = down;
		}

		public MaxNumber add(int up, int down) {
			if (this.down == down) {
				this.up = this.up + up;
			} else {
				int gcd = this.gcd(this.down, down);
				int mul1 = this.down / gcd;
				int mul2 = down / gcd;
				this.down = this.down * mul2;
				this.up = this.up * mul2 + up * mul1;
			}
			this.div();
			return this;
		}

		public MaxNumber sub(int up, int down) {
			if (this.down == down) {
				this.up = this.up - up;
			} else {
				int gcd = this.gcd(this.down, down);
				int mul1 = this.down / gcd;
				int mul2 = down / gcd;
				this.down = this.down * mul2;
				this.up = this.up * mul2 - up * mul1;
			}
			this.div();
			return this;
		}

		private void div() {
			int gcd = Math.abs(gcd(this.down, this.up));
			this.down = this.down / gcd;
			this.up = this.up / gcd;
		}

		private int gcd(int a, int b) {
			return b == 0 ? a : gcd(b, a % b);
		}

		@Override
		public String toString() {
			StringBuffer sb = new StringBuffer();
			sb.append(this.up).append("/").append(this.down);
			return sb.toString();
		}
	}

	public static void main(String[] args) {
		Solution so = new Solution();
		so.debug1();
		so.debug2();
		so.debug3();
		so.debug4();

	}

}
